package com.freedy.concurrent.OptimisticLock;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author Freedy
 * @date 2021/4/23 21:16
 */
public class AccountTest {
    public static void main(String[] args) {
        AccountCAS cas = new AccountCAS(10000);
        Account.demo(cas);
    }
}

class AccountCAS implements Account{

    private final AtomicInteger balance;

    public AccountCAS(int balance) {
        this.balance=new AtomicInteger(balance);
    }

    @Override
    public Integer getBalance() {
        return balance.get();
    }

    @Override
    public void withdraw(Integer amount) {
        for (;;){
            int prev=balance.get();
            int next = prev - amount;;
            if (balance.compareAndSet(prev,next))
                break;
        }
    }
}


interface Account {
    // 获取余额
    Integer getBalance();
    // 取款
    void withdraw(Integer amount);
    /**
     * 方法内会启动 1000 个线程，每个线程做 -10 元 的操作
     * 如果初始余额为 10000 那么正确的结果应当是 0
     */
    static void demo(Account account) {
        List<Thread> ts = new ArrayList<>();
        long start = System.nanoTime();
        for (int i = 0; i < 1000; i++) {
            ts.add(new Thread(() -> {
                account.withdraw(10);
            }));
        }
        ts.forEach(Thread::start);
        ts.forEach(t -> {
            try {
                t.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        long end = System.nanoTime();
        System.out.println(account.getBalance()
                + " cost: " + (end-start)/1000_000 + " ms");
    }
}